#include "syn_tri.h"
#include "syn_data.h" //本模块是对此平台的适配器，依赖通用的应用逻辑

//应用使用的函数
extern void SysTick_Delay(u32 n); //延时死等,单位us

//设备：
//1. AMP1：PA1，AMP2：PB0
//2. AD：ADC1-IN13，规则通道
//3. TIM：TIM2-CH1-PA0输入（PPS），CH2-PWM无输出，触发
//4. DMA：DMA1-CH3连续模式，配半满中断和完成中断

void amp_ini(void)
{ //测试阶段使用放大8倍的PGA模式正向放大
	RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; 
	GPIO_Set(GPIOA, PIN1, GPIO_MODE_AIN, GPIO_OTYPE_PP, GPIO_SPEED_HIGH, GPIO_PUPD_NONE);
	GPIO_Set(GPIOB, PIN0, GPIO_MODE_AIN, GPIO_OTYPE_PP, GPIO_SPEED_HIGH, GPIO_PUPD_NONE);
	//配置寄存器
	OPAMP1->CSR = (0<<17) | //0:内部，1:负输入接PGA的地
		(2 << 14) | //增益：2/4/8/16/32/64(2是8倍)
		(1 << 8) | //输出接AD，断开引脚
		(1 << 7) | //高速模式
		(2 << 5) | //第一负向输入PA3,PC5,PGA,跟随器
		(0 << 2) | //第一正向输入PA1 PA3 PA7 DAC3_CH1
		(0 << 1) | //校准
		(1 << 0); //使能
	OPAMP2->CSR = (0<<17) | //负输入接PGA的地
		(2 << 14) | //增益：2/4/8/16/32/64(2是8倍)
		(1 << 8) | //输出接AD，断开引脚
		(1 << 7) | //高速模式
		(2 << 5) | //第一负向输入PA3,PC5,PGA,跟随器
		(2 << 2) | //第一正向输入PA7 PB14 PB0 PD14
		(0 << 1) | //校准
		(1 << 0); //使能
}
void adc_ini(void)
{
//主要关注的：
//	1、时钟频率，来源
//	2、参考源
//	3、上电等20us
//	4、注入与规则通道的冲突
//AD时钟(最高约52MHz)
	RCC->AHB2ENR |= RCC_AHB2ENR_ADC12EN;
	//RCC->CCIPR |= RCC_CCIPR_ADC12SEL_1; //选择AD的时钟源
//AD的时钟：用PLLP优点是能达到最高频率，用系统时钟有利于定时器触发，因为不跨时钟域
	RCC->CCIPR |= (1<<28); //1：PLLP；2：系统时钟。320MHz/6 = 53.3MHz
	RCC->AHB2RSTR |= RCC_AHB2ENR_ADC12EN;
	RCC->AHB2RSTR &= ~RCC_AHB2ENR_ADC12EN;
//开参考源(不开默认是外部参考)
	//RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; //开时钟
	//VREFBUF->CSR=(1<<4) | 1;//0：2.048V，1：2.5V，2：2.9V
	//开电源
	//ADC12_COMMON->CCR|=(2<<18); //0/2/4分频,160MHz/4=40MHz 调试器中看没赋上值
	ADC1->CR = 0; //关闭深度睡眠
	ADC1->CR |= (1<<28); //开电源
//////////////////////////////////////////////////////////////////
	SysTick_Delay(100); //开电源后必须等待(手册写的20us)
//////////////////////////////////////////////////////////////////
	//校准
	ADC1->CR |= (1<<31); //校准
	while(ADC1->CR & (1<<31));
	//配置采样速度
	//1为6.5,6.5+12.5=19周，475ns(40MHz)，4个一共1.9us
	//3为24.5,24.5+12.5=37周，925ns
	//7为640.5,640.5+12.5=653周，16.3us
	ADC1->SMPR1 = (3<<3) | (3<<6) | (3<<9) | (3<<12) |
			(3<<15) | (3<<18) | (3<<21) | (3<<24); //转换速度
	ADC1->SMPR2 = (3<<0) | (3<<3) | (3<<6) | (3<<9) | (1<<12) |
			(1<<15) | (3<<18) | (3<<21) | (3<<24); //转换速度，通道13是bit9
	//配置规则通道
	ADC1->SQR1 = 0 | //规则通道的数量，0是1个，1是2个
			(13<<6) | (11<<12) | (14<<18) | (4<<24);
	ADC1->SQR2 = 5 | (6<<6) | (7<<12) | (8<<18);
	ADC1->CFGR |=   (0<<13) | //CONT 连续模式(造成注入通道第一次采样值为0)
			(1<<12) | //OVRMOD 新的转换覆盖旧的
			(1<<10) | //EXTEN 外部触发：0不触发，1上升沿，2下降沿，3双边沿
			(3<<5) | //EXTSEL 触发事件：3: TIM2-CC2
			(1<<1) | //DMACFG DMA环形模式
			(1<<0); //DMAEN DMA使能
	ADC1->CFGR2 |= (0<<5) | //右移bit数
			//(7<<2) | //256倍过采样20bit
			(1<<2) | //4倍过采样
			3; //注入和规则通道过采样

	//配置DMA
	RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
	RCC->AHB1ENR |= RCC_AHB1ENR_DMAMUX1EN;
	DMA1_Channel3->CCR = (0<<12) | //PL 优先级0~3，3最高
			(1<<10) | //MSIZE 8/16/32
			(1<<8) | //PSIZE 8/16/32  外设宽度
			(1<<7) | //存储器增量
			(0<<6) | //外设增量
			(1<<5) | //循环
			(0<<4) | //DIR 0:从外设读，1：从内存读
			(1<<2) | //半满中断
			(1<<1);//传输完成中断
	//(1<<0)//EN只能在最后写否则数量寄存器就写不上了
	DMA1_Channel3->CNDTR = SYN_PACK_SIZE; //传输数量
	DMA1_Channel3->CPAR = (u32) & (ADC1->DR); //外设地址
	DMA1_Channel3->CMAR = (u32)synd_ring_buf; //存储器地址
	DMAMUX1_Channel2->CCR = 5; //ADC1
	DMA1_Channel3->CCR |= (1<<0); //使能
	MY_NVIC_Init(0,0,DMA1_Channel3_IRQn,0); //配置DMA中断
	//开始转换
	ADC1->CR |= 1; //ADEN开始
	while((ADC1->ISR & (1<<0)) == 0); //等ADC ready
	ADC1->CR |= (1<<2); //ADSTART开始转换规则通道: 开始后才接受外部触发

	ADC1->ISR |= (1<<4) | (1<<6); //OVR写1清零
}
void tim_ini(void)
{ //配置12.8KHz周期中断、pps(PA0)中断、pps的reset触发
	GPIO_Set(GPIOA,PIN0,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_HIGH,GPIO_PUPD_PU);
	GPIO_AF_Set(GPIOA,0,1);

	RCC->APB1ENR1|=RCC_APB1ENR1_TIM2EN;

	TIM2->CR1 = 0x0080 | (0<<5); //不分频，边沿PWM
	TIM2->CR2 = 0; //
	//TIM2->CR2=(7<<4); //用CH4做AD的触发
	TIM2->SMCR=(1<<7) | //从模式
		(4<<4) |//触发源:110 tim_ti1f_ed
		(4); //从模式：0100: reset mode		发生tim_ti1f_ed时，清零计数器
	TIM2->DIER = (1<<0) | (1<<6);	     //UIE TIE的中断允许
	TIM2->CCMR1=0x6801;		 //通道1输入，通道2输出PWM
	//TIM2->CCMR2=0x6868;
	TIM2->CCER=0;		//通道输出不允许，
	TIM2->PSC=0;		//160MHz 不分频
	TIM2->ARR=12499;	//自动装载寄存器，频率12.8KHz
	TIM2->CCR1=0;		//通道1输入，不关心
	TIM2->CCR2=6250;	//通道2输出，占空比50%
	TIM2->EGR=1;		//UG置一

	MY_NVIC_Init(0,0,TIM2_IRQn,0); //第二路电机的处理中断
}
void synt_ini(void)
{
	amp_ini();
	adc_ini();
	tim_ini();
}
//////////////////////////////////////////////////////////////////////////////
extern "C"
{
void DMA1_Channel3_IRQHandler(void);
void TIM2_IRQHandler(void);
}
#define DMA_CH3_SHIFT	((3-1)*4)
void DMA1_Channel3_IRQHandler(void) //AD的DMA中断
{
	//缓存中断标志
	u32 isr = DMA1->ISR;
	//清除中断标志
	DMA1->IFCR = 0xf<<DMA_CH3_SHIFT; //清所有中断,3号,AD的
	//处理
	if(isr & (4<<DMA_CH3_SHIFT)) //半满
	{
		synd_in_half_INTR(0);
	}
	else if(isr & (2<<DMA_CH3_SHIFT)) //完成
	{
		synd_in_half_INTR(1);
	}
}

void TIM2_IRQHandler(void)
{
	u32 t = TIM2->SR;
	TIM2->SR = 0; //软件写0清除
	if(t & (1<<0)) //UIF: PPS中断，先处理
	{
		synd_pps_INTR();
	}
	if(t & (1<<6)) //TIF: 周期守时中断，后处理
	{
		synd_TIM_INTR();
	}
}
